import { io } from "socket.io-client"
import WebrtcConnection from './WebrtcConnection'

const socket = io("https://localhost:3000")

socket.on("connect", () => {
  console.log("Connected to server")

  socket.on("message", (payload) => {
    const {type, data} = payload
    switch(type) {
      case "joinRoom":
        receiveJoinRoom(data)
        break;
      case "offer":
        receiveOffer(data)
        break;
      case "answer":
        receiveAnswer(data)
        break;
      case "candidate":
        receiveCandidate(data)
        break;
      default:
    }
  })
})

const startBtn = document.getElementById("start")
const toggleBtn = document.getElementById("stop")
const shareBtn = document.getElementById("share")
const localVideo = document.getElementById("localVideo")
let roomId;
let userId;
let connection; 
let mediaStream;
let playing = false;

startBtn.addEventListener("click",  async() => {
  roomId = document.getElementById("roomId").value
  userId = document.getElementById("userId").value
  if (!roomId || !userId) {
    alert("请输入房间号和用户ID")
    return
  }
  if (!connection) {
    socket.emit("joinRoom", { roomId, userId })
  } else {
    // 切换媒体流时才会用到
    mediaStream = await createlocalStream()
    if (mediaStream) {
      connection.setStreamToVideoElm(localVideo, mediaStream)
      connection.changeSendersTrack(mediaStream)
    }
  }
})

toggleBtn.addEventListener("click", () => {
  playing = !playing
  connection.toggleVideoTrack(mediaStream, playing)
})

shareBtn.addEventListener("click", async() => {
  mediaStream = await navigator.mediaDevices.getDisplayMedia({
    video: true,
  })
  if (mediaStream) {
    connection.setStreamToVideoElm(localVideo, mediaStream)
    connection.changeSendersTrack(mediaStream)
  }
})


// 1. 输入房间号跟用户ID后，先加入一个固定ID的房间（call）
// 2. 当房间只有自己时，先播放本地流
 
// 用户进入房间时的通知
async function receiveJoinRoom(reply){
  const { roomCount } = reply

  if (!connection || connection.peerconnection.connectionState === "closed") {
      // 获取本地流
    mediaStream = await createlocalStream()

    // 创建 RTC 实例连接
    connection = getPeerConnection()

    // 将流注入到本地视频标签中
    connection.setStreamToVideoElm(localVideo, mediaStream)

    // 将本地流加入到 RTC 实例中
    connection.addTrack(mediaStream)

    if (roomCount > 1) {
      // 创建本地 offer、设为本地 offer、发送本地 offer
      const offer = await connection.createAndSetLocalOffer()
      socket.emit("offer", {roomId, offer})
    } else {
      alert("房间内只有自己，请等待其他用户加入")
    }
  }
}

async function receiveOffer(reply){
  const { offer } = reply
  // 获取 RTC 实例
  const connection = getPeerConnection()
  // 将远程 offer 设为存入到 RTC 中
  connection.setRemoteDescription(offer)
  // 创建本地 answer、设为本地 answer、发送本地 answer
  const answer = await connection.createAndSetLocalAnswer()
  socket.emit("answer", { roomId, answer })
}

function receiveAnswer(reply){
  const { answer } = reply
  const connection = getPeerConnection()
  connection.setRemoteDescription(answer)
}

function receiveCandidate(reply){
  const { candidate } = reply
  const connection = getPeerConnection()
  connection.setRemoteCandidate(candidate)
}

// 从媒体设备获取音视频流
async function createlocalStream(){
  let mediaStream;
  try {
    mediaStream = await navigator.mediaDevices.getUserMedia(
      {
        video: true,
        audio: true
      }
    )
    return mediaStream
  } catch (err) {
    console.log(err)
    // 由于我的电脑没有两个摄像头，因此先用共享桌面作为媒体流替代
    mediaStream = await navigator.mediaDevices.getDisplayMedia(
      {
        video: true,
        audio: true
      }
    )
    return mediaStream
  }
}

function setRemoteVideo(stream) {
  const video = document.getElementById("remoteVideo")
  video.srcObject = stream
}

function getPeerConnection(){
  if (!connection) { 
    connection = new WebrtcConnection();
    connection.create((candidate) => {
      socket.emit("candidate", { roomId, candidate });
    }, (event) => {
      const { streams } = event;
      setRemoteVideo(streams[0])
      playing = true;
    });
  }
  
  return connection; 
}
